import java.io.FileOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.BufferedReader;
import java.io.FileReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.lang.String;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

public class wget 
{
	public static void main(String[] args) 
	{
		int ret = 0;

		if (args.length == 0) 
		{
			usage();
		}
		
		if ( args[0].equals ("install") )
		{
			if (args.length == 1)
			{
				ret = install ( "wget.list" );
			}
			else
			{
				for (int i = 1; i < args.length; i++)
				{
					ret = install ( args[i] );
				}
			}
		}
		else if ( args[0].equals("get") )
		{
			if ( args.length != 3)
			{
				usage();
			}
			
			ret = download ( args[1], args[2] );
		}
		else if ( args[0].equals("unzip") )
		{
			if ( args.length != 3)
			{
				usage();
			};
			
			ret = unzip (args[1], args[2]);
		}
		else
		{
			usage();
		}

		if (ret != 0 )
		{
			System.exit (ret);
		}
	}

	private static void usage() 
	{
		System.out.println ("USAGE: ");
		System.out.println (" java -jar wget.jar get filename URL");
		System.out.println (" java -jar wget.jar unzip filename path");
		System.out.println (" java -jar wget.jar install list1 list2 ...");
		System.exit(0);
	}

	private static boolean forceCreatePath (String sPath)
	{
		File f = new File (sPath);
		
		if (f.exists())
		{
			return f.isDirectory();
		}
		
		return f.mkdirs();
	};
	
	public static int unzip (String filename, String path)
	{
		byte[] buff = new byte[8 * 1024];
		int buff_size;

		if (path == null || path.equals ("") )
		{
			int ind = filename.lastIndexOf('.');
			
			if (ind <=0) return 1;
			
			path = filename.substring (0, ind);
		};
		
		path = path.replace('/', File.separatorChar);
		filename = filename.replace('/', File.separatorChar);
	
		try
		{	
			ZipInputStream in = new ZipInputStream (new FileInputStream(filename));
	
			ZipEntry z;
	
			while ((z=in.getNextEntry() )!= null)
			{
				String name = path + File.separator + z.getName().replace("/", File.separator);
				String ffPath;
				
				if (z.isDirectory()) 
				{
					ffPath = name.substring(0,name.length()-1);
					
					if ( ! forceCreatePath (ffPath) )
					{
						System.out.println ("Create Directory failed:" + ffPath );
					}
					else
					{
						System.out.println("make dir " + ffPath);						
					}
					continue;
				}
				
				ffPath = name.substring (0, name.lastIndexOf(File.separator));
				
				System.out.println("unziping " + name );
					
				if ( ! forceCreatePath (ffPath) )
				{
					System.out.println ("Create Directory failed:" + ffPath );
					continue;
				}

				File f = new File ( name );
			
				if ( !f.createNewFile())
				{
					f.delete();
					if ( ! f.createNewFile() )
					{
						System.out.println ("Create file " + name + "failed" );
					}
				}
				
				FileOutputStream out = new FileOutputStream(f);

				while ((buff_size = in.read(buff)) != -1)
				{
					out.write(buff,0, buff_size);
				}
			
				out.close();
			}
	
			in.close();
		}
		catch (IOException io)
		{
			return 2;
		};
	
		return 0;
	};
	
	public static int install (String filename)
	{		
		filename = filename.replace('/', File.separatorChar);
		ArrayList<String> lines = new ArrayList<String>();
		filename = (new File(filename)).getAbsolutePath();
		String strBasePath = "";
		int cmd,ind;
		boolean os_limit = false; 
		
		if (filename == null)
		{
			return 1;
		};
		
		ind = filename.lastIndexOf(File.separatorChar);
		
		if (ind>=0)
		{
			strBasePath = filename.substring (0, ind);
		}
		
		if (strBasePath.length() == 0)
		{
			strBasePath = ".";
		}
		
		try
		{
			BufferedReader rd = new BufferedReader ( new FileReader (filename) );
			String s;

			while ( (s = rd.readLine()) != null )
			{
				lines.add(s.trim());
			}
		}
		catch (IOException io) 
		{
		}

		cmd = 1;
		for (int i = 0; i<lines.size(); i++)
		{
			String l = lines.get(i).trim();
			
			if (l.startsWith("--"))
			{
				continue;
			}
			
			if (l.startsWith(":install"))
			{
				cmd = 1;
				continue;
			}
			
			if (l.startsWith(":download"))
			{
				cmd = 2;
				continue;
			}
			
			if (l.startsWith(":include"))
			{
				cmd = 3;
				continue;
			}
			if (l.startsWith(":os=windows"))
			{
				os_limit = !System.getProperty("os.name").toLowerCase().startsWith("win");
				continue;
			}
			
			if (l.startsWith(":os=linux"))
			{
				os_limit = System.getProperty("os.name").toLowerCase().startsWith("win");
				continue;
			}
			
			if (l.startsWith(":os="))
			{
				os_limit = false;
				continue;
			}
			
			if (os_limit)
			{
				System.out.println("skiping(os-limit)" + l );
				continue;
			}
			
			if (cmd == 3)
			{
				install ( strBasePath + File.separator + l );
				continue;
			};
			
			ind = l.indexOf(" ");
			if (ind <= 0) continue;
		 
			String sName = l.substring (0, ind).replace('/', File.separatorChar);
			String sURL	= l.substring (ind + 1).trim();
		 
			download (strBasePath + File.separator + sName, sURL);
			
			if (cmd == 1 && sName.toLowerCase().endsWith(".zip"))
			{
				unzip (sName, null);
			}
		}
		
		return 0;
	};
	
	public static int download (String filename, String sURL)
	{
		filename = filename.replace('/', File.separatorChar);
		
		if ((new File(filename)).exists())
		{	
			System.out.println (filename + " already exists");
			return 0;
		}
	
		try
		{
			URL theURL = new URL (sURL);
			URLConnection con;
			int total_size;
		
			con = theURL.openConnection ();
			con.connect ();
		
			String type = con.getContentType ();
			total_size = con.getContentLength ();
		
			System.out.println ("begin download " + filename + "(from " + sURL + ")" );
			System.out.println ("Content Type:" + type);
			System.out.println ("Content Size:" + total_size );
			
			if (type == null)
			{
				return 1;
			};
		
			byte[] buffer = new byte[16 * 1024];
			int read,count = 0;
			
			FileOutputStream os = new FileOutputStream (filename);
			InputStream in = con.getInputStream();
		
			
			total_size = total_size >= 100 ? total_size / 100 : 1;
			
			while ((read = in.read(buffer)) > 0) 
				{
				os.write(buffer, 0, read);
				count += read;
			
				System.out.print ( "downloading " + count + " (" + (count / total_size) + "%)\r" );
			}
			
			System.out.println ("download finished                        ");
			
			os.close();
			in.close();
		} 
		catch (MalformedURLException e) 
		{
			e.printStackTrace();
			return 2;
		}
		catch (Exception e) 
		{
			e.printStackTrace();
			return 3;
		}
		
		return 0;
	}
}
